/*
 * BPlusTreeNode.h
 *
 *  Created on: 16-Oct-2013
 *      Author: sriram
 */
/*
 * The BPlusTree is defined by the following terms:
 * Properties of B-Tree
1) All leaves are at same level.
2) A B-Tree is defined by the term minimum degree ‘t’. The value of t depends upon disk block size.
3) Every node except root must contain at least t-1 keys. Root may contain minimum 1 key.
4) All nodes (including root) may contain at most 2t – 1 keys.
5) Number of children of a node is equal to the number of keys in it plus 1.
6) All keys of a node are sorted in increasing order. The child between two keys k1 and k2 contains all keys in range from k1 and k2.
7) B-Tree grows and shrinks from root which is unlike Binary Search Tree. Binary Search Trees grow downward and also shrink from downward.
8) Like other balanced Binary Search Trees, time complexity to search, insert and delete is O(Logn).
 *
 */
#ifndef BPLUSTREENODE_H_
#define BPLUSTREENODE_H_
//#include "../Utils/MemoryManagement.h"
//#include "../Global/BaseEntity.h"
#include "../Global/StructureHeaders.h"
#include "IndexHeaderPage.h"

class BPlusTreeNode {
private:
    bool isIndexGenerated;
    typedef struct GeneralNodeStruct {
        PageHeader pgHeader; // General Page Header
        int leftPGNumber, rightPGNumber; // Left and right pages to the node
        int level, noKeys, parentPGNumber, indexHeaderPGNumber;
    } GeneralNodeHeaderStructure;

    GeneralNodeHeaderStructure generalNodePageHeader_; // General - (Root, Internal) Node header
    IndexHeaderPage *indexHeaderPage_; // Metadata of Index
    char *pageData_;

public:
    BPlusTreeNode();
    BPlusTreeNode(int nodePageNumber);
    BPlusTreeNode(IndexHeaderPage *indexHeaderPage, int indexPageNumber);
    int search(char *key);
    int search(char *key, int noColumns);
    int insertsearch(char *key);
    int contains(char *key);
    int containsColumns(char *key, int noColumns);
    virtual ~BPlusTreeNode();
    static int getBPlusGeneralNodeHeaderSize();
    STATUS_CODE create(IndexHeaderPage* indexHeaderPage);
    STATUS_CODE insert(const char *key, int leftPageNumber, int rightPageNumber);
    STATUS_CODE append(const char *key, int rightPageNumber);
    STATUS_CODE insertFront(const char *key, int leftPageNumber);
    STATUS_CODE remove(char *key, int nextPage, bool isRightMerge, vector<int> &arrDeletedPages);
    
    int getPageNumber();
    int getIndexHeaderPageNumber();
    int getLevel();
    int getParentPageNumber();
    int getNoKeys();
    int getLeftPageNumber();
    int getRightPageNumber();
    int getFirstChildPageNumber();
    void getPrevKeytoPage(int page, char *key);
    void getFirstKey(char *key);
    void getFirstPage(int &firstPageNumber);
    void getLastKey(char *key);
    void getLastPage(int &firstPageNumber);
    void removeFirstPageKey();
    void removeLastPageKey();
    STATUS_CODE getSiblingsToPage(int page, int &leftPageNumber, int &rightPageNumber);
    
    STATUS_CODE updateKey(char *key, char *updatedKey);
    STATUS_CODE updatePrevKeyToPageNumber(int pageNumber, char *key, char *replaceKey);

    void setPageNumber(int pageNumber);
    void setIndexHeaderPageNumber(int indexHeaderPageNumber);
    void setLevel(int level);
    void setParentPageNumber(int parentPageNumber);
    void setNoKeys(int noKeys);
    void setLeftPageNumber(int leftPageNumber);
    void setRightPageNumber(int rightPageNumber);
    
    string toString();
    string toShortString();
    
    // Checking Consistency of the node
    vector<int> getAllPages();
    bool isPageNumberPresent(int pageNumber);
    bool checkConsistency();
};

#endif /* BPLUSTREENODE_H_ */
